package cn.yunyichina.reservation.launch;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.filter.HttpPutFormContentFilter;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.*;
import java.util.EnumSet;
import java.util.Set;

/**
 * Created by Lullaby on 2016/8/18.
 */
public class Initializer implements ServletContainerInitializer {

    private static final Logger logger = LoggerFactory.getLogger(Initializer.class);

    private static final String SPRING_CONFIGURATION = "classpath:application-context.xml";

    private static final String SPRING_SERVLET_NAME = "spring";

    private static final String DISPATCHER_MAPPING = "/";

    private static final String HTTP_ENCODING_NAME = "encoding";

    private static final String HTTP_ENCODING = "UTF-8";

    private static final String MULTIPART_CONFIG_LOCATION = "/tmp";
    private static final long MULTIPART_CONFIG_MAX_FILE_SIZE = 20848820;
    private static final long MULTIPART_CONFIG_MAX_REQUEST_SIZE = 418018841;
    private static final int MULTIPART_CONFIG_FILE_SIZE_THRESHOLD = 1048576;

    public void onStartup(Set<Class<?>> classes, ServletContext servletContext)
            throws ServletException {
        long start = System.currentTimeMillis();
        try {
            FilterRegistration.Dynamic springEncodingFilter = servletContext.addFilter("springEncodingFilter", CharacterEncodingFilter.class);
            springEncodingFilter.setInitParameter(HTTP_ENCODING_NAME, HTTP_ENCODING);
            springEncodingFilter.setInitParameter("forceResponseEncoding", String.valueOf(true));
            springEncodingFilter.addMappingForServletNames(EnumSet.allOf(DispatcherType.class), true, SPRING_SERVLET_NAME);

            FilterRegistration.Dynamic hiddenHttpMethodFilter = servletContext.addFilter("hiddenHttpMethodFilter", HiddenHttpMethodFilter.class);
            hiddenHttpMethodFilter.setInitParameter(HTTP_ENCODING_NAME, HTTP_ENCODING);
            hiddenHttpMethodFilter.addMappingForServletNames(EnumSet.allOf(DispatcherType.class), true, SPRING_SERVLET_NAME);

            FilterRegistration.Dynamic httpPutFormContentFilter = servletContext.addFilter("httpPutFormContentFilter", HttpPutFormContentFilter.class);
            httpPutFormContentFilter.setInitParameter(HTTP_ENCODING_NAME, HTTP_ENCODING);
            httpPutFormContentFilter.addMappingForServletNames(EnumSet.allOf(DispatcherType.class), true, SPRING_SERVLET_NAME);

            XmlWebApplicationContext springContext = new XmlWebApplicationContext();
            springContext.setConfigLocation(SPRING_CONFIGURATION);
            ServletRegistration.Dynamic spring = servletContext.addServlet(SPRING_SERVLET_NAME, new DispatcherServlet(springContext));
            MultipartConfigElement multipartConfigElement = new MultipartConfigElement(
                    MULTIPART_CONFIG_LOCATION,
                    MULTIPART_CONFIG_MAX_FILE_SIZE,
                    MULTIPART_CONFIG_MAX_REQUEST_SIZE,
                    MULTIPART_CONFIG_FILE_SIZE_THRESHOLD
            );
            spring.setLoadOnStartup(0);
            spring.setMultipartConfig(multipartConfigElement);
            spring.addMapping(DISPATCHER_MAPPING);
        } catch (Exception e) {
            logger.error("`Initializer init error`", e);
        }
        long end = System.currentTimeMillis();
        long spend = end - start;
        logger.info("`Initializer init in " + spend + " ms`");
    }

}
